/**
 * @PoolManager.as
 *
 * @author sodaChen mail:asframe@qq.com
 * @version 1.0
 * <br>Copyright (C), 2012 ASFrame.com
 * <br>This program is protected by copyright laws.
 * <br>Program Name:ASFrame
 * <br>Date:2013-6-20
 */
package com.asframe.mgr
{
	import com.asframe.Const;
	import com.asframe.collections.maps.HashMap;
	import com.asframe.lang.Assert;
	import com.asframe.pattern.Singleton;
	import com.asframe.pool.IObjectPool;
	import com.asframe.pool.ObjectPool;

	/**
	 * 对象池管理器包括IObjectPool的对象，实现了统一管理。具体使用到了pool包里面的各种对象池的实例和接口
	 * @author sodaChen
	 * #Date:2013-6-20
	 */
	public class PoolMgr extends Singleton
	{
		private static var instance:PoolMgr;
		/** 构造器的函数名称：constructor **/
		private static const CONSTRUCTOR_NAME:String = Const.CONSTRUCTOR_NAME;

		/** 默认一个对象池的最大空闲对象是数量 **/
		public var defaultMax:int = 20;
		/** 对象池集合 **/
		private var _poolMap:HashMap;
		/** 一次取对象池时的缓存对象，主要用于提升性能 ，避免经常产生临时变量 **/
		private var _tempPool:IObjectPool;

		public function PoolMgr()
		{
			_poolMap = new HashMap();
		}
		/**
		 * 获取实例的静态方法实例
		 * @return PoolMgr实例
		 */
		public static function getInstance():PoolMgr
		{
			if(instance == null)
			{
				instance = new PoolMgr();
			}
			return instance;
		}
		/**
		 * 获取到指定对象池对象
		 * @param clazz 对象池缓存的对象Class
		 * @return 返回指定的对象池对象
		 *
		 */
		public function getObjectPool(clazz:Class):IObjectPool
		{
			return _poolMap.get(clazz);
		}
		/**
		 * 注册一个需要缓存池的Class对象，内部会自动生成通用的ObjectPool对象池
		 * @param clazz 缓存对象class
		 * @param maxIdle 最大的空闲数量
		 * @param hasStatus 是否需要做激活和不激活的状态检测(false有助提升性能)
		 *
		 */
		public function registerClass(clazz:Class, maxIdle:int = -1,hasStatus:Boolean = false):void
		{
			if(_poolMap.hasKey(clazz)) return;//注册过1次就不能再注册了
			if(maxIdle == -1)
				maxIdle = defaultMax;
			_tempPool = new ObjectPool(clazz,maxIdle,hasStatus);
			_poolMap.put(clazz,_tempPool);
		}
		/**
		 * 注册一个对象池，由外部提供对象池
		 * @param clazz 生产的对象class
		 * @param objectPool 对象池实例
		 */
		public function registerPool(clazz:Class, objectPool:IObjectPool):void
		{
			_poolMap.put(clazz,objectPool);
		}
		/**
		 * 清除指定的对象池
		 * @param clazz 对象class
		 * @param isDestory 是否同时销毁。默认false
		 */
		public function clearPool(clazz:Class,isDestory:Boolean = false):void
		{
			_tempPool = _poolMap.get(clazz);
			Assert.notNull(_tempPool,clazz + "没有对应的对象池");
			if(isDestory)
			{
				_tempPool.destroy();
				_poolMap.remove(clazz);
			}
			else
			{
				_tempPool.clear();
			}
		}
		/**
		 * 借出一个对象(借出的对象，对象池和管理器本身不会对它有任何引用，完全干净无引用的对象)
		 * @param clazz
		 * @return
		 *
		 */
		public function borrowObject(clazz:Class):*
		{
			_tempPool = _poolMap.get(clazz);
			if(!_tempPool)return null;
			return _tempPool.borrowObject();
		}
		/**
		 * 归还对象。如果对象池满了，则会进行销毁。调用dispose方法或者IDestroy接口的方法
		 * @param obj 实例
		 * @param clazz 对象class.为空时则会自动从obj上获取到对应的class
		 */
		public function returnObject(obj:*,clazz:Class = null):void
		{
			if(clazz == null)
				clazz = obj[CONSTRUCTOR_NAME];

			_tempPool = _poolMap.get(clazz);
			_tempPool.returnObject(obj);
		}

		/**
		 * 是否已满
		 * @param obj
		 * @param clazz
		 * @return
		 *
		 */
		public function isFull(obj:*,clazz:Class = null):Boolean
		{
			if(clazz == null)
				clazz = obj[CONSTRUCTOR_NAME];

			_tempPool = _poolMap.get(clazz);
			return _tempPool.isFull(obj);
		}
	}
}
